using System;
using System.Data;
using System.Data.SqlClient;
using Csla;
using Csla.Data;
using Csla.Validation;
using BA.DAL;
using BA;
using System.Text;

namespace BlazeApps.Library.Form
{
    [Serializable()]
    public class FormResponse : Csla.BusinessBase<FormResponse>
    {
        private BlazeApps.Library.ConfigSettings Config = new BlazeApps.Library.ConfigSettings();
        private BA.DAL.DBUtility DAL = new BA.DAL.DBUtility();
        private Procedures Procs = new Procedures();

        #region Business Properties and Methods

        //declare members
        private Guid _formID = Guid.NewGuid();
        private Guid _formResponseID = Guid.NewGuid();
        private string _takenBy = string.Empty;
        private SmartDate _takenDate = new SmartDate(DateTime.Today);
        private bool _reviewed = false;
        private Guid _reviewedBy = Guid.Empty;
        private string _reviewerComments = string.Empty;
        private SmartDate _reviewedDate = new SmartDate(false);

        public Guid FormID
        {
            get
            {
                CanReadProperty("FormID", true);
                return _formID;
            }
            set
            {
                CanWriteProperty("FormID", true);
                if (!_formID.Equals(value))
                {
                    _formID = value;
                    PropertyHasChanged("FormID");
                }
            }
        }

        [System.ComponentModel.DataObjectField(true, true)]
        public Guid FormResponseID
        {
            get
            {
                CanReadProperty("FormResponseID", true);
                return _formResponseID;
            }
            set
            {
                CanWriteProperty("FormResponseID", true);
                if (!_formResponseID.Equals(value))
                {
                    _formResponseID = value;
                    PropertyHasChanged("FormResponseID");
                }
            }
        }

        public string TakenBy
        {
            get
            {
                CanReadProperty("TakenBy", true);
                return _takenBy;
            }
            set
            {
                CanWriteProperty("TakenBy", true);
                if (value == null)
                    value = string.Empty;
                if (!_takenBy.Equals(value))
                {
                    _takenBy = value;
                    PropertyHasChanged("TakenBy");
                }
            }
        }

        public DateTime TakenDate
        {
            get
            {
                CanReadProperty("TakenDate", true);
                return _takenDate.Date;
            }
        }

        public string TakenDateString
        {
            get
            {
                CanReadProperty("TakenDate", true);
                return _takenDate.Text;
            }
            set
            {
                CanWriteProperty("TakenDate", true);
                if (value == null)
                    value = string.Empty;
                if (!_takenDate.Equals(value))
                {
                    _takenDate.Text = value;
                    PropertyHasChanged("TakenDate");
                }
            }
        }

        public bool Reviewed
        {
            get
            {
                CanReadProperty("Reviewed", true);
                return _reviewed;
            }
            set
            {
                CanWriteProperty("Reviewed", true);
                if (!_reviewed.Equals(value))
                {
                    _reviewed = value;
                    PropertyHasChanged("Reviewed");
                }
            }
        }

        public Guid ReviewedBy
        {
            get
            {
                CanReadProperty("ReviewedBy", true);
                return _reviewedBy;
            }
            set
            {
                CanWriteProperty("ReviewedBy", true);
                if (!_reviewedBy.Equals(value))
                {
                    _reviewedBy = value;
                    PropertyHasChanged("ReviewedBy");
                }
            }
        }

        public string ReviewerComments
        {
            get
            {
                CanReadProperty("ReviewerComments", true);
                return _reviewerComments;
            }
            set
            {
                CanWriteProperty("ReviewerComments", true);
                if (value == null)
                    value = string.Empty;
                if (!_reviewerComments.Equals(value))
                {
                    _reviewerComments = value;
                    PropertyHasChanged("ReviewerComments");
                }
            }
        }

        public DateTime ReviewedDate
        {
            get
            {
                CanReadProperty("ReviewedDate", true);
                return _reviewedDate.Date;
            }
        }

        public string ReviewedDateString
        {
            get
            {
                CanReadProperty("ReviewedDate", true);
                return _reviewedDate.Text;
            }
            set
            {
                CanWriteProperty("ReviewedDate", true);
                if (value == null)
                    value = string.Empty;
                if (!_reviewedDate.Equals(value))
                {
                    _reviewedDate.Text = value;
                    PropertyHasChanged("ReviewedDate");
                }
            }
        }

        protected override object GetIdValue()
        {
            return _formResponseID;
        }

        #endregion //Business Properties and Methods

        #region Validation Rules
        private void AddCustomRules()
        {
            //add custom/non-generated rules here...
        }

        private void AddCommonRules()
        {
            //
            // TakenDate
            //
            ValidationRules.AddRule(CommonRules.StringRequired, "TakenDateString");
        }

        protected override void AddBusinessRules()
        {
            AddCommonRules();
            AddCustomRules();
        }
        #endregion //Validation Rules

        #region Authorization Rules
        protected override void AddAuthorizationRules()
        {
            //TODO: Define authorization rules in FormResponse
            //AuthorizationRules.AllowRead("FormID", "FormResponseReadGroup");
            //AuthorizationRules.AllowRead("FormResponseID", "FormResponseReadGroup");
            //AuthorizationRules.AllowRead("TakenBy", "FormResponseReadGroup");
            //AuthorizationRules.AllowRead("TakenDate", "FormResponseReadGroup");

            //AuthorizationRules.AllowWrite("TakenBy", "FormResponseWriteGroup");
            //AuthorizationRules.AllowWrite("TakenDate", "FormResponseWriteGroup");
        }


        public static bool CanGetObject()
        {
            //TODO: Define CanGetObject permission in FormResponse
            return true;
            //if (Csla.ApplicationContext.User.IsInRole("FormResponseViewGroup"))
            //	return true;
            //return false;
        }

        public static bool CanAddObject()
        {
            //TODO: Define CanAddObject permission in FormResponse
            return true;
            //if (Csla.ApplicationContext.User.IsInRole("FormResponseAddGroup"))
            //	return true;
            //return false;
        }

        public static bool CanEditObject()
        {
            //TODO: Define CanEditObject permission in FormResponse
            return true;
            //if (Csla.ApplicationContext.User.IsInRole("FormResponseEditGroup"))
            //	return true;
            //return false;
        }

        public static bool CanDeleteObject()
        {
            //TODO: Define CanDeleteObject permission in FormResponse
            return true;
            //if (Csla.ApplicationContext.User.IsInRole("FormResponseDeleteGroup"))
            //	return true;
            //return false;
        }
        #endregion //Authorization Rules

        #region Factory Methods
        private FormResponse()
        { /* require use of factory method */
        }

        public static FormResponse NewFormResponse()
        {
            if (!CanAddObject())
                throw new System.Security.SecurityException("User not authorized to add a FormResponse");
            return DataPortal.Create<FormResponse>();
        }

        public static FormResponse GetFormResponse(Guid formResponseID)
        {
            if (!CanGetObject())
                throw new System.Security.SecurityException("User not authorized to view a FormResponse");
            return DataPortal.Fetch<FormResponse>(new Criteria(formResponseID));
        }

        public static void DeleteFormResponse(Guid formResponseID)
        {
            if (!CanDeleteObject())
                throw new System.Security.SecurityException("User not authorized to remove a FormResponse");
            DataPortal.Delete(new Criteria(formResponseID));
        }

        public override FormResponse Save()
        {
            if (IsDeleted && !CanDeleteObject())
                throw new System.Security.SecurityException("User not authorized to remove a FormResponse");
            else if (IsNew && !CanAddObject())
                throw new System.Security.SecurityException("User not authorized to add a FormResponse");
            else if (!CanEditObject())
                throw new System.Security.SecurityException("User not authorized to update a FormResponse");

            return base.Save();
        }

        #endregion //Factory Methods

        #region Data Access

        #region Criteria

        [Serializable()]
        private class Criteria
        {
            public Guid FormResponseID;

            public Criteria(Guid formResponseID)
            {
                this.FormResponseID = formResponseID;
            }
        }

        #endregion //Criteria

        #region Data Access - Create
        [RunLocal]
        protected override void DataPortal_Create()
        {
            ValidationRules.CheckRules();
        }

        #endregion //Data Access - Create

        #region Data Access - Fetch
        private void DataPortal_Fetch(Criteria criteria)
        {
            ExecuteFetch(criteria);
        }

        private void ExecuteFetch(Criteria criteria)
        {

            DAL.CreateDBObjects(Config.ConnectionString, Config.Provider);

            DAL.AddParameter("@FormResponseID", criteria.FormResponseID);

            using (SafeDataReader dr = new SafeDataReader(DAL.ExecuteReader(Procs.GetFormResponseByResponseID.ToString().Trim(), CommandType.Text, ConnectionState.Open)))
            {
                FetchObject(dr);
                ValidationRules.CheckRules();

                //load child object(s)
                FetchChildren(dr);
            }
        }

        private void FetchObject(SafeDataReader dr)
        {
            dr.Read();
            _formID = dr.GetGuid("FormID");
            _formResponseID = dr.GetGuid("FormResponseID");
            _takenBy = dr.GetString("TakenBy");
            _takenDate = dr.GetSmartDate("TakenDate", _takenDate.EmptyIsMin);
            _reviewed = dr.GetBoolean("Reviewed");
            _reviewedBy = dr.GetGuid("ReviewedBy");
            _reviewerComments = dr.GetString("ReviewerComments");
            _reviewedDate = dr.GetSmartDate("ReviewedDate", _reviewedDate.EmptyIsMin);
        }

        private void FetchChildren(SafeDataReader dr)
        {
        }
        #endregion //Data Access - Fetch

        #region Data Access - Insert
        protected override void DataPortal_Insert()
        {
            ExecuteInsert();
        }

        private void ExecuteInsert()
        {
            DAL.CreateDBObjects(Config.ConnectionString, Config.Provider);

            AddInsertParameters(ref DAL);

            DAL.ExecuteNonQuery(Procs.InsertFormResponse.ToString().Trim(), CommandType.Text, ConnectionState.Open);
        }

        private void AddInsertParameters(ref BA.DAL.DBUtility DAL)
        {
            DAL.AddParameter("@FormID", _formID);
            DAL.AddParameter("@FormResponseID", _formResponseID);
            if (_takenBy != string.Empty)
                DAL.AddParameter("@TakenBy", _takenBy);
            else
                DAL.AddParameter("@TakenBy", DBNull.Value);
            DAL.AddParameter("@TakenDate", _takenDate.DBValue);
            //if (_reviewed != false)
            //    DAL.AddParameter("@Reviewed", _reviewed);
            //else
            //    DAL.AddParameter("@Reviewed", DBNull.Value);
            //if (_reviewedBy != Guid.Empty)
            //    DAL.AddParameter("@ReviewedBy", _reviewedBy);
            //else
            //    DAL.AddParameter("@ReviewedBy", DBNull.Value);
            //if (_reviewerComments != string.Empty)
            //    DAL.AddParameter("@ReviewerComments", _reviewerComments);
            //else
            //    DAL.AddParameter("@ReviewerComments", DBNull.Value);
            //DAL.AddParameter("@ReviewedDate", _reviewedDate.DBValue);
        }
        #endregion //Data Access - Insert

        #region Data Access - Update
        protected override void DataPortal_Update()
        {
            if (base.IsDirty)
            {
                ExecuteUpdate();
            }
        }

        private void ExecuteUpdate()
        {
            DAL.CreateDBObjects(Config.ConnectionString, Config.Provider);

            AddUpdateParameters(ref DAL);

            DAL.ExecuteNonQuery(Procs.UpdateFormResponse.ToString().Trim(), CommandType.Text, ConnectionState.Open);
        }

        private void AddUpdateParameters(ref BA.DAL.DBUtility DAL)
        {
            DAL.AddParameter("@FormID", _formID);
            DAL.AddParameter("@FormResponseID", _formResponseID);
            if (_takenBy != string.Empty)
                DAL.AddParameter("@TakenBy", _takenBy);
            else
                DAL.AddParameter("@TakenBy", DBNull.Value);
            DAL.AddParameter("@TakenDate", _takenDate.DBValue);
            if (_reviewed != false)
                DAL.AddParameter("@Reviewed", _reviewed);
            else
                DAL.AddParameter("@Reviewed", DBNull.Value);
            if (_reviewedBy != Guid.Empty)
                DAL.AddParameter("@ReviewedBy", _reviewedBy);
            else
                DAL.AddParameter("@ReviewedBy", DBNull.Value);
            if (_reviewerComments != string.Empty)
                DAL.AddParameter("@ReviewerComments", _reviewerComments);
            else
                DAL.AddParameter("@ReviewerComments", DBNull.Value);
            DAL.AddParameter("@ReviewedDate", _reviewedDate.DBValue);
        }

        private void UpdateChildren(SqlConnection cn)
        {
        }
        #endregion //Data Access - Update

        #region Data Access - Delete
        protected override void DataPortal_DeleteSelf()
        {
            DataPortal_Delete(new Criteria(_formResponseID));
        }

        private void DataPortal_Delete(Criteria criteria)
        {
            ExecuteDelete(criteria);
        }

        private void ExecuteDelete(Criteria criteria)
        {
            DAL.CreateDBObjects(Config.ConnectionString, Config.Provider);

            AddDeleteParameters(ref DAL, criteria);

            DAL.ExecuteNonQuery(Procs.DeleteFormResponse.ToString().Trim(), CommandType.Text, ConnectionState.Open);
        }

        private void AddDeleteParameters(ref BA.DAL.DBUtility DAL, Criteria criteria)
        {
            DAL.AddParameter("@FormResponseID", DbType.Guid, criteria.FormResponseID);
        }
        #endregion //Data Access - Delete
        #endregion //Data Access
    }
}
